/**
 * 统一监控系统
 * 整合性能监控、错误监控、用户行为追踪和智能上报
 */

import { PerformanceCollector } from './performance-collector';
import { ErrorCollector } from './error-collector';
import { MonitorReporter } from './reporter';
import { BehaviorTracker } from './behavior-tracker';
import { ConfigManager } from './config-manager';
import type {
  BaseMonitorData,
  MonitorConfig,
  PerformanceMetrics,
  JavaScriptErrorInfo,
  NetworkErrorInfo,
  VueErrorInfo,
  UserBehaviorData,
} from '~/types/monitor';

export class UnifiedMonitor {
  private performanceCollector: PerformanceCollector;
  private reporter: MonitorReporter;
  private behaviorTracker: BehaviorTracker;
  private configManager: ConfigManager;
  private config: MonitorConfig;
  private isInitialized: boolean = false;
  private errorBoundary: boolean = true;

  constructor() {
    // 只能在浏览器环境中使用
    if (typeof window === 'undefined' || typeof document === 'undefined') {
      throw new Error('监控工具只能在浏览器环境中使用');
    }

    try {
      this.initializeMonitor();
    } catch (error) {
      console.error('❌ [统一监控系统] 初始化失败:', error);
      this.errorBoundary = false;
    }
  }

  /**
   * 初始化监控系统
   */
  private initializeMonitor(): void {
    // 初始化配置管理器
    this.configManager = ConfigManager.getInstance();
    this.config = this.configManager.getConfig();

    // 初始化各个组件
    this.reporter = new MonitorReporter();
    this.performanceCollector = new PerformanceCollector();
    this.behaviorTracker = new BehaviorTracker();

    // 监听配置变化
    this.configManager.onConfigChange(newConfig => {
      this.config = newConfig;
      this.handleConfigChange(newConfig);
    });

    // 设置全局错误处理
    this.setupGlobalErrorHandlers();

    // 设置页面卸载时的清理
    this.setupCleanup();

    this.isInitialized = true;

    console.log('🔍 [统一监控系统] 初始化完成', {
      project: this.config.projectName,
      environment: process.env.NODE_ENV,
      features: {
        performance: this.config.enablePerformanceMonitor,
        error: this.config.enableErrorMonitor,
        behavior: this.config.enableUserBehavior,
      },
    });
  }

  /**
   * 处理配置变化
   */
  private handleConfigChange(newConfig: MonitorConfig): void {
    console.log('⚙️ [监控系统] 配置已更新', newConfig);

    // 根据新配置重新初始化组件
    if (!newConfig.enableUserBehavior) {
      this.behaviorTracker.destroy();
    }
  }

  /**
   * 设置全局错误处理
   */
  private setupGlobalErrorHandlers(): void {
    if (!this.config.enableErrorMonitor) return;

    // JavaScript错误
    window.addEventListener('error', event => {
      this.safeExecute(() => {
        this.reportJavaScriptError(
          event.message,
          event.filename,
          event.lineno,
          event.colno,
          event.error?.stack
        );
      });
    });

    // Promise未捕获错误
    window.addEventListener('unhandledrejection', event => {
      this.safeExecute(() => {
        const reason = event.reason;
        const message =
          reason instanceof Error ? reason.message : String(reason);
        const stack = reason instanceof Error ? reason.stack : undefined;

        this.reportJavaScriptError(
          `Unhandled Promise Rejection: ${message}`,
          undefined,
          undefined,
          undefined,
          stack
        );
      });
    });

    // 资源加载错误
    window.addEventListener(
      'error',
      event => {
        this.safeExecute(() => {
          const target = event.target as HTMLElement;
          if (target && target !== window) {
            this.reportResourceError(target);
          }
        });
      },
      true
    );
  }

  /**
   * 安全执行函数，避免监控代码影响主业务
   */
  private safeExecute(fn: () => void): void {
    if (!this.errorBoundary) return;

    try {
      fn();
    } catch (error) {
      console.warn('❌ [监控系统] 内部错误:', error);
      // 监控系统出错时暂时禁用，避免循环错误
      this.errorBoundary = false;
      setTimeout(() => {
        this.errorBoundary = true;
      }, 5000);
    }
  }

  /**
   * 设置清理逻辑
   */
  private setupCleanup(): void {
    const cleanup = () => {
      this.safeExecute(() => {
        // 上报最后的性能数据
        this.reportPerformance();

        // 清理资源
        this.disconnect();
      });
    };

    window.addEventListener('beforeunload', cleanup);
    window.addEventListener('pagehide', cleanup);
  }

  /**
   * 上报基础监控数据
   */
  report(data: BaseMonitorData): void {
    this.safeExecute(() => {
      if (!this.isInitialized) return;

      // 添加用户行为上下文
      if (this.config.enableUserBehavior) {
        const recentBehaviors = this.behaviorTracker.getRecentBehaviors(5);
        if (recentBehaviors.length > 0) {
          data.userBehaviors = recentBehaviors;
        }
      }

      this.reporter.report(data);
    });
  }

  /**
   * 立即上报重要数据
   */
  async reportImmediately(data: BaseMonitorData): Promise<boolean> {
    if (!this.isInitialized) return false;

    return new Promise(resolve => {
      this.safeExecute(async () => {
        const result = await this.reporter.reportImmediately(data);
        resolve(result);
      });
    });
  }

  /**
   * 上报JavaScript错误
   */
  reportJavaScriptError(
    message: string,
    source?: string,
    line?: number,
    column?: number,
    stack?: string
  ): void {
    this.safeExecute(() => {
      const errorInfo = ErrorCollector.collectJavaScriptError(
        message,
        source,
        line,
        column,
        stack
      );

      this.report({
        level: 'error',
        type: 'js',
        message: `JS错误: ${errorInfo.chineseMessage}`,
        url: source,
        stack,
        line,
        column,
        originalMessage: errorInfo.originalMessage,
        errorType: errorInfo.type,
      });
    });
  }

  /**
   * 上报资源加载错误
   */
  reportResourceError(element: HTMLElement): void {
    this.safeExecute(() => {
      const tagName = element.tagName.toLowerCase();
      const src = (element as any).src || (element as any).href;

      this.report({
        level: 'error',
        type: 'js',
        message: `资源加载失败: ${tagName}`,
        url: src,
        resourceType: tagName,
      });
    });
  }

  /**
   * 上报网络请求错误
   */
  reportNetworkError(
    url: string,
    message: string,
    status?: number,
    method?: string,
    requestData?: any,
    responseData?: any,
    duration?: number
  ): void {
    this.safeExecute(() => {
      const errorInfo = ErrorCollector.collectNetworkError(
        url,
        method || 'GET',
        message,
        status,
        undefined,
        requestData,
        responseData,
        duration
      );

      this.report({
        level: 'error',
        type: 'network',
        message: `网络错误: ${errorInfo.chineseMessage}`,
        url,
        status,
        method,
        duration,
        originalMessage: errorInfo.originalMessage,
      });
    });
  }

  /**
   * 上报Vue组件错误
   */
  reportVueError(message: string, component?: string, stack?: string): void {
    this.safeExecute(() => {
      const errorInfo = ErrorCollector.collectVueError(
        message,
        component,
        stack
      );

      this.report({
        level: 'error',
        type: 'vue',
        message: `Vue错误: ${errorInfo.message}`,
        component,
        stack,
      });
    });
  }

  /**
   * 上报API数据异常（警告级别）
   */
  reportApiDataWarning(url: string, message: string, data?: any): void {
    this.safeExecute(() => {
      this.report({
        level: 'warn',
        type: 'api',
        message: `API数据异常: ${message}`,
        url,
        responseData: data,
      });
    });
  }

  /**
   * 上报一般信息
   */
  reportInfo(message: string, extraData?: Record<string, any>): void {
    this.safeExecute(() => {
      this.report({
        level: 'info',
        message,
        ...extraData,
      });
    });
  }

  /**
   * 上报性能数据
   */
  reportPerformance(): void {
    this.safeExecute(() => {
      if (!this.config.enablePerformanceMonitor) return;

      const metrics = this.performanceCollector.getMetrics();
      const resourceMetrics = this.performanceCollector.getResourceMetrics();
      const advice = this.performanceCollector.getPerformanceAdvice();

      // 检查性能警告 - DOM就绪耗时大于4s为警告
      const hasPerformanceIssue =
        metrics.documentInteractiveTime &&
        metrics.documentInteractiveTime >= 4000;

      // 如果DOM就绪耗时小于4s，不上报（参考headScripts.js逻辑）
      if (!hasPerformanceIssue) return;

      // 构建基础性能数据（参考performance.js的basic字段）
      const basicData: any = {};
      if (window.performance && window.performance.timing) {
        const timing = window.performance.timing;
        basicData.loadEventStart = timing.loadEventStart;
        basicData.navigationStart = timing.navigationStart;
        basicData.fetchStart = timing.fetchStart;
        basicData.domainLookupEnd = timing.domainLookupEnd;
        basicData.domainLookupStart = timing.domainLookupStart;
        basicData.connectEnd = timing.connectEnd;
        basicData.connectStart = timing.connectStart;
        basicData.responseStart = timing.responseStart;
        basicData.requestStart = timing.requestStart;
        basicData.responseEnd = timing.responseEnd;
        basicData.domInteractive = timing.domInteractive;
        basicData.domContentLoadedEventEnd = timing.domContentLoadedEventEnd;
      }

      // 构建完整的性能消息（参考headScripts.js格式）
      const performanceMessage = {
        网页加载总耗时: metrics.pageLoadTime,
        重定向耗时: metrics.redirectionTime,
        域名解析耗时: metrics.domainLookupTime,
        建立连接耗时: metrics.serverConnectionTime,
        服务器响应耗时: metrics.serverResponseTime,
        HTML下载耗时: metrics.pageDownloadTime || metrics.serverResponseTime, // 使用serverResponseTime作为fallback
        DOM就绪耗时: metrics.documentInteractiveTime,
        'DOM/CSSOM/JS完成耗时': metrics.documentContentLoadedTime,
        // 添加增强指标
        性能评分: metrics.performanceScore,
        首次内容绘制: metrics.FCP,
        最大内容绘制: metrics.LCP,
        首次输入延迟: metrics.FID,
        累积布局偏移: metrics.CLS,
        首字节时间: metrics.TTFB,
        资源数量: metrics.resourceCount,
        包大小: metrics.bundleSize,
        长任务数量: metrics.longTaskCount,
        总阻塞时间: metrics.totalBlockingTime,
        内存使用: metrics.memoryUsage,
        ...basicData,
      };

      // 按照headScripts.js的格式上报
      this.report({
        title: `networkException ${window.location.pathname}`,
        logType: 'networkException',
        code: 408,
        level: 'warn',
        type: 'performance',
        message: JSON.stringify(performanceMessage),
        url: window.location.pathname,
        // 额外的调试信息
        performanceScore: metrics.performanceScore,
        advice: advice.length > 0 ? advice : undefined,
        resourceMetrics: Object.fromEntries(resourceMetrics),
      });
    });
  }

  /**
   * 获取性能指标
   */
  getPerformanceMetrics(): PerformanceMetrics {
    return this.performanceCollector.getMetrics();
  }

  /**
   * 获取用户行为数据
   */
  getUserBehaviors(count?: number): UserBehaviorData[] {
    return this.behaviorTracker.getRecentBehaviors(count);
  }

  /**
   * 测量自定义指标
   */
  mark(name: string): void {
    this.safeExecute(() => {
      this.performanceCollector.mark(name);
    });
  }

  /**
   * 测量两个标记之间的时间
   */
  measure(name: string, startMark: string, endMark?: string): number {
    if (!this.isInitialized) return 0;

    return this.performanceCollector.measure(name, startMark, endMark);
  }

  /**
   * 更新配置
   */
  updateConfig(newConfig: Partial<MonitorConfig>): void {
    this.safeExecute(() => {
      this.configManager.updateConfig(newConfig);
    });
  }

  /**
   * 获取当前配置
   */
  getConfig(): MonitorConfig {
    return this.configManager.getConfig();
  }

  /**
   * 获取性能建议
   */
  getPerformanceAdvice(): string[] {
    return this.performanceCollector.getPerformanceAdvice();
  }

  /**
   * 获取系统状态
   */
  getSystemStatus(): {
    isInitialized: boolean;
    errorBoundary: boolean;
    config: MonitorConfig;
    performanceScore?: number;
  } {
    return {
      isInitialized: this.isInitialized,
      errorBoundary: this.errorBoundary,
      config: this.config,
      performanceScore: this.performanceCollector.getMetrics().performanceScore,
    };
  }

  /**
   * 清理资源
   */
  disconnect(): void {
    this.safeExecute(() => {
      this.performanceCollector.disconnect();
      this.behaviorTracker.destroy();
      this.reporter.destroy();
    });
  }
}

/**
 * 全局监控实例
 */
let globalMonitor: UnifiedMonitor | null = null;

/**
 * 获取监控实例的工具函数
 */
export function useMonitor(): UnifiedMonitor {
  if (!globalMonitor && process.client) {
    try {
      globalMonitor = new UnifiedMonitor();
    } catch (error) {
      console.error('❌ [监控系统] 初始化失败:', error);
      throw error;
    }
  }
  return globalMonitor!;
}

// 导出类型和工具类
export type * from '~/types/monitor';
export {
  ErrorCollector,
  PerformanceCollector,
  MonitorReporter,
  BehaviorTracker,
  ConfigManager,
};
export default UnifiedMonitor;
